package auth

import (
	"fmt"
	"sync"

	"GinAdmin/core/database"

	"github.com/casbin/casbin/v2"
	"github.com/casbin/casbin/v2/model"
	gormadapter "github.com/casbin/gorm-adapter/v3"
)

// Enforcer 全局Casbin执行器
var (
	Enforcer *casbin.Enforcer
	once     sync.Once
)

// InitCasbin 初始化Casbin
func InitCasbin() error {
	var err error
	once.Do(func() {
		// 创建适配器
		adapter, adapterErr := gormadapter.NewAdapterByDB(database.DB)
		if adapterErr != nil {
			err = fmt.Errorf("failed to create Casbin adapter: %w", adapterErr)
			return
		}

		// 创建Casbin模型
		m, modelErr := model.NewModelFromString(`
[request_definition]
r = sub, obj, act

[policy_definition]
p = sub, obj, act

[role_definition]
g = _, _

[policy_effect]
e = some(where (p.eft == allow))

[matchers]
m = g(r.sub, p.sub) && r.obj == p.obj && r.act == p.act
`)
		if modelErr != nil {
			err = fmt.Errorf("failed to create Casbin model: %w", modelErr)
			return
		}

		// 创建Casbin执行器
		Enforcer, err = casbin.NewEnforcer(m, adapter)
		if err != nil {
			err = fmt.Errorf("failed to create Casbin enforcer: %w", err)
			return
		}

		// 加载策略
		err = Enforcer.LoadPolicy()
		if err != nil {
			err = fmt.Errorf("failed to load Casbin policy: %w", err)
			return
		}
	})

	return err
}

// CheckPermission 检查用户权限
func CheckPermission(sub string, obj string, act string) (bool, error) {
	if Enforcer == nil {
		return false, fmt.Errorf("casbin enforcer not initialized")
	}
	return Enforcer.Enforce(sub, obj, act)
}

// AddPolicy 添加策略
func AddPolicy(sub string, obj string, act string) (bool, error) {
	if Enforcer == nil {
		return false, fmt.Errorf("casbin enforcer not initialized")
	}
	return Enforcer.AddPolicy(sub, obj, act)
}

// AddRoleForUser 为用户添加角色
func AddRoleForUser(user string, role string) (bool, error) {
	if Enforcer == nil {
		return false, fmt.Errorf("casbin enforcer not initialized")
	}
	return Enforcer.AddGroupingPolicy(user, role)
}

// DeleteRoleForUser 删除用户角色
func DeleteRoleForUser(user string, role string) (bool, error) {
	if Enforcer == nil {
		return false, fmt.Errorf("casbin enforcer not initialized")
	}
	return Enforcer.RemoveGroupingPolicy(user, role)
}

// GetRolesForUser 获取用户角色
func GetRolesForUser(user string) ([]string, error) {
	if Enforcer == nil {
		return nil, fmt.Errorf("casbin enforcer not initialized")
	}
	return Enforcer.GetRolesForUser(user)
}
